package com.bobo.mm.socket;

import android.content.Context;
import android.util.Log;

import com.bobo.mm.ClientConfig;
import com.bobo.mm.ISocketListener;
import com.bobo.mm.SocketFrameworkType;
import com.bobo.mm.socket.decoder.DecoderFactory;
import com.bobo.mm.socket.provider.BlockSocketClient;
import com.bobo.mm.socket.provider.ISocketClient;
import com.bobo.mm.socket.provider.NioSocketClient;
import com.bobo.mm.socket.provider.OkWebSocketClient;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * socket客户端管理类
 * Created by cocolove2 on 2020/5/22.
 */
final class SocketManager {
    private static final String TAG = "SocketManager";
    /**
     * 客户端字典表
     */
    private Map<ClientConfig, ISocketClient> clientMap = new ConcurrentHashMap<>(2);

    private SocketManager() {
    }

    private static class SocketManagerHolder {
        private static final SocketManager INSTANCE = new SocketManager();
    }

    static SocketManager getInstance() {
        return SocketManager.SocketManagerHolder.INSTANCE;
    }


    void start(final Context context, ClientConfig config, ISocketListener listener) {
        if (config == null || !config.isValid()) {
            throw new IllegalArgumentException("[CSocket]--初始化配置为空，或者参数不合法，服务启动失败");
        }
        ISocketClient socketProvider;
        //初始化socket框架
        if (SocketFrameworkType.SOCKET_JAVA_BLOCK.equals(config.getFrameworkType())) {
            socketProvider = new BlockSocketClient(config, new InnerSocketListener(listener),
                    DecoderFactory.create(config.getDecodeClsName(), config.getDecodeMaxLength()));
        } else if (SocketFrameworkType.WEBSOCKET_OKHTTP.equals(config.getFrameworkType())) {
            socketProvider = new OkWebSocketClient(config, new InnerSocketListener(listener));
        } else if (SocketFrameworkType.SOCKET_JAVA_NIO.equals(config.getFrameworkType())) {
            socketProvider = new NioSocketClient(config, new InnerSocketListener(listener),
                    DecoderFactory.create(config.getDecodeClsName(), config.getDecodeMaxLength()));
        } else {
            throw new UnsupportedOperationException("[CSocket]--未知框架类型，不支持，服务启动失败");
        }
        clientMap.put(config, socketProvider);
        socketProvider.startConnect();
    }


    private ISocketClient getSocketProvider(String channelId) {
        ClientConfig config = new ClientConfig(channelId);
        return clientMap.get(config);
    }

    void stop(String channelId) {
        ISocketClient socketProvider = getSocketProvider(channelId);
        if (socketProvider != null) {
            socketProvider.stopConnect();
        } else {
            Log.e(TAG, "找不到相应的SocketProvider:" + channelId);
        }
    }

    void stopAll() {
        for (Map.Entry<ClientConfig, ISocketClient> item : clientMap.entrySet()) {
            item.getValue().stopConnect();
        }
    }

    boolean sendMessage(String channelId, String message) {
        ISocketClient socketProvider = getSocketProvider(channelId);
        if (socketProvider != null) {
            return socketProvider.sendMessage(message);
        } else {
            Log.e(TAG, "找不到相应的SocketProvider:" + channelId);
            return false;
        }
    }

    boolean sendMessage(String channelId, byte[] message) {
        ISocketClient socketProvider = getSocketProvider(channelId);
        if (socketProvider != null) {
            return socketProvider.sendMessage(message);
        } else {
            Log.e(TAG, "找不到相应的SocketProvider:" + channelId);
            return false;
        }
    }

    boolean isConnected(String channelId) {
        ISocketClient socketProvider = getSocketProvider(channelId);
        if (socketProvider != null) {
            return socketProvider.isConnected();
        } else {
            Log.e(TAG, "找不到相应的SocketProvider:" + channelId);
            return false;
        }
    }

}
